#include "binary_buffer.h"
#include <string.h>
#include <stdio.h>

// 创建缓冲区，支持传入已有的 uint8_t 数组或指定大小
BinaryBuffer* createBuffer(size_t size, uint8_t* array) {
    BinaryBuffer* b = (BinaryBuffer*)malloc(sizeof(BinaryBuffer));

    if (array != NULL) {
        b->buffer = array;   // 直接使用外部缓冲区，避免复制
        b->capacity = size;
        b->externalBuffer = 1; // 标记为外部缓冲区
    } else {
        b->buffer = (uint8_t*)malloc(size);
        b->capacity = size;
        b->externalBuffer = 0; // 标记为内部缓冲区
    }

    b->writePos = 0;
    b->readPos = 0;
    return b;
}

// 确保缓冲区有足够空间（仅在使用内部缓冲区时有效）
void ensureSize(BinaryBuffer* b, size_t size) {
    if (b->externalBuffer) {
        // 如果是外部缓冲区，无法扩展，跳过此操作
        return;
    }
    if (b->writePos + size > b->capacity) {
        size_t newCapacity = b->capacity * 2 + size;
        b->buffer = (uint8_t*)realloc(b->buffer, newCapacity);
        b->capacity = newCapacity;
    }
}

// 获取当前数据长度
size_t getDataLength(BinaryBuffer* b) {
    return b->writePos;
}

// 获取缓冲区总长度
size_t getBufferLength(BinaryBuffer* b) {
    return b->capacity;
}
// 写入 Int32 值
void writeInt32(BinaryBuffer* b, int32_t value) {
    ensureSize(b, sizeof(int32_t));
    memcpy(&b->buffer[b->writePos], &value, sizeof(int32_t));
    b->writePos += sizeof(int32_t);
}

// 写入 Uint32 值
void writeUint32(BinaryBuffer* b, uint32_t value) {
    ensureSize(b, sizeof(uint32_t));
    memcpy(&b->buffer[b->writePos], &value, sizeof(uint32_t));
    b->writePos += sizeof(uint32_t);
}

// 写入 Uint8 值
void writeUint8(BinaryBuffer* b, uint8_t value) {
    ensureSize(b, sizeof(uint8_t));
    b->buffer[b->writePos] = value;
    b->writePos += sizeof(uint8_t);
}
void writeFloat32(BinaryBuffer* b, float value){
    ensureSize(b, sizeof(float));
    memcpy(&b->buffer[b->writePos], &value, sizeof(float));
    b->writePos += sizeof(float);
}

// 读取 Int32 值
int32_t readInt32(BinaryBuffer* b) {
    int32_t value;
    memcpy(&value, &b->buffer[b->readPos], sizeof(int32_t));
    b->readPos += sizeof(int32_t);
    return value;
}

// 读取 Uint32 值
uint32_t readUint32(BinaryBuffer* b) {
    uint32_t value;
    memcpy(&value, &b->buffer[b->readPos], sizeof(uint32_t));
    b->readPos += sizeof(uint32_t);
    return value;
}

// 读取 Uint8 值
uint8_t readUint8(BinaryBuffer* b) {
    uint8_t value = b->buffer[b->readPos];
    b->readPos += sizeof(uint8_t);
    return value;
}
float readFloat32(BinaryBuffer* b){
    float value;
    memcpy(&value, &b->buffer[b->readPos], sizeof(float));
    b->readPos += sizeof(float);
    return value;
}

// 根据索引读取 Int32
int32_t readInt32At(BinaryBuffer* b, size_t index) {
    int32_t value;
    memcpy(&value, &b->buffer[index], sizeof(int32_t));
    return value;
}

// 根据索引读取 Uint32
uint32_t readUint32At(BinaryBuffer* b, size_t index) {
    uint32_t value;
    memcpy(&value, &b->buffer[index], sizeof(uint32_t));
    return value;
}

// 根据索引读取 Uint8
uint8_t readUint8At(BinaryBuffer* b, size_t index) {
    return b->buffer[index];
}
float readFloat32At(BinaryBuffer* b, size_t index){
    float value;
    memcpy(&value, &b->buffer[index], sizeof(float));
    return value;
}
// 根据索引写入 Int32
void writeInt32At(BinaryBuffer* b, size_t index, int32_t value) {
    memcpy(&b->buffer[index], &value, sizeof(int32_t));
}

// 根据索引写入 Uint32
void writeUint32At(BinaryBuffer* b, size_t index, uint32_t value) {
    memcpy(&b->buffer[index], &value, sizeof(uint32_t));
}

// 根据索引写入 Uint8
void writeUint8At(BinaryBuffer* b, size_t index, uint8_t value) {
    b->buffer[index] = value;
}
void writeFloat32At(BinaryBuffer* b, size_t index, float value){
    memcpy(&b->buffer[index], &value, sizeof(float));
}
// 清理缓冲区
void freeBuffer(BinaryBuffer* b) {
    // 仅当缓冲区是内部缓冲区时才释放
    if (!b->externalBuffer) {
        free(b->buffer);
    }
    free(b);
}
